﻿using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;

namespace HealthMonitor.Extensions
{
    /// <summary>
    /// A class for serialization and object mapping
    /// Use the xOnex versions for one-off, the instance methods for repetition
    /// </summary>
    public class Serialization
    {
        
        //readonly JsonSerializer jss;
        readonly JavaScriptSerializer jss;
        public Serialization()
        {
            this.jss = new JavaScriptSerializer();
        }
        public Serialization(JavaScriptSerializer jss):this()
        {
            Guard.ThrowIfNull(() => jss);
        }
        public string Serialize(object obj)
        {
            return jss.Serialize(obj);
        }
        public T Deserialize<T>(string json)
        {
            return jss.Deserialize<T>(json);
        }
        public T MapUsingSerializer<T>(object source)
        {
            var serialized = Serialize(source);
            return Deserialize<T>(serialized);
        }
        public object Deserialize(string input, Type targetType)
        {
            if (targetType.IsInterface)//IEnumerable, IList, IAssociate etc..?
            {
                if (targetType.GetInterface("IEnumerable") != null && targetType.IsGenericType)
                {
                    var newType = typeof(List<>).MakeGenericType(targetType.GetGenericArguments());

                    return new JavaScriptSerializer().Deserialize("[" + input + "]", newType);
                }


            }
            return new JavaScriptSerializer().Deserialize(input, targetType);
        }

        /// <summary>
        /// allows you to specify extra source -> destination mappings
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="extraMappings"></param>
        /// <returns></returns>
        public TResult MapUsingSerializer<T, TResult>(T source, IDictionary<string, string> extraMappings)
        {
            var j = new JavaScriptSerializer();
            var s = j.Serialize(source);
            Func<string, string> jsonColumnFormatter = x => //"BankRole":
                                                                                                       '"' + x + '"' + ":";
            foreach (var item in extraMappings.Maybe())

                s = s.Replace(jsonColumnFormatter(item.Key), jsonColumnFormatter(item.Value));
            //var r=s.Replace("Name", "DealName");

            return j.Deserialize<TResult>(s);
        }


    }
}